home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / inter52f.zip / INT2RTF.ZIP / INT2RTF.PAS < prev    next >
Pascal/Delphi Source File  |  1996-10-09  |  56KB  |  1,435 lines

  1. { INT2RTF. Main module for the Interrupt List -> .RTF compiler.}
  2. { The software included, data formats and basic algorithms are }
  3. { copyright (C) 1996 by Slava Gostrenko. All rights reserved.  }
  4.  
  5. {$M 16384}
  6. {$IFNDEF DPMI}
  7.   ! set Target to 'Protected Mode Application'
  8. {$ENDIF}
  9.  
  10. {$X+}
  11. program
  12.   Int2RTF;
  13.  
  14. uses
  15.   Upcaser, Objects, RTF;
  16.  
  17. var
  18.   FO: THelpFile;
  19.   IncompPattern: Text;
  20.   Hdrs: TStringCollection;
  21.   IntLists: array [Byte] of PTopic;
  22.   IntNames: array [Byte] of string [12];
  23.   KeyLists: TCollection;
  24.   KeyNames: TCollection;
  25.   IntList: PTopic;
  26.   IntListName: string;
  27.   Tables: PTopic;
  28.   TablesName: string;
  29.   CMOS: PTopic;
  30.   CMOSName: string;
  31.   FARCall: PTopic;
  32.   FARCallName: string;
  33.   Memory: PTopic;
  34.   MemoryName: string;
  35.   Ports: PTopic;
  36.   PortSName: string;
  37.  
  38.   IntListIndex: PTopic;
  39.   IntListIndexName: string;
  40.   Interrup1st: Text;
  41.   CopyrightStr: string;
  42.  
  43. const HexCh: array [0..$F] of Char = '0123456789ABCDEF';
  44. function HexWord (W: Word): string;
  45. begin
  46.   HexWord := HexCh[Hi(W) shr 4] + HexCh[Hi(W) and $F]
  47.            + HexCh[Lo(W) shr 4] + HexCh[Lo(W) and $F];
  48. end;
  49. function HexByte (B: Byte): string;
  50. begin
  51.   HexByte := HexCh[B shr 4] + HexCh[B and $F];
  52. end;
  53.  
  54. function MemInitSwapFile(FileName: PChar; FileSize: Longint): Integer; far; external 'RTM' Index 35;
  55. function MemCloseSwapFile(Delete: Integer): Integer; far; external 'RTM' Index 36;
  56.  
  57. function MakeCorrectTopicName (const TopicName: string): string;
  58. var
  59.   I: Integer;
  60.   V: Integer;
  61.   AddChar, TstTopic: string;
  62.   Rez: string;
  63. begin
  64.   Rez := TopicName;
  65.  
  66.   V := 0;
  67.  
  68.   AddChar := '';
  69.  
  70.   TstTopic := StUpcase2 (Rez);
  71.   while Hdrs. Search (@TstTopic, I) do begin
  72.     Dec (Rez [0], Length (AddChar));
  73.     Inc (V);
  74.     if V > 99 then
  75.       WriteLn ('error 3');
  76.  
  77.     System. Str (V, AddChar);
  78.     if Length (AddChar) = 1 then
  79.       AddChar := '_0' + AddChar
  80.     else
  81.       AddChar := '_'  + AddChar;
  82.  
  83.     Rez := Rez + AddChar;
  84.     TstTopic := StUpcase2 (Rez);
  85.   end;
  86.  
  87.   Hdrs. Insert (NewStr (TstTopic));
  88.  
  89.   MakeCorrectTopicName := Rez;
  90. end;
  91.  
  92. function ProcessPattern (var Str: string; var Pos: Integer;
  93.                          Pattern: string; Keyword: string;
  94.                          Topic: PTopic; StepBack: Integer): Boolean;
  95. var I, J: Integer;
  96. begin
  97.   I := 1;
  98.   while I <= Length (Pattern) do begin
  99.     if Pattern [I] in [#3, #6] then
  100.       if Upcase [Str [Pos + I - 1]] in HexChars + ['X'] then begin
  101.         J := System. Pos (#3, Keyword);
  102.         if J > 0 then
  103.           Keyword [J] := Str [Pos + I - 1]
  104.         else
  105.           if Pattern [I] = #3 then begin
  106.             WriteLn (Str);
  107.             WriteLn ('error in keyword pattern (1) ', Pattern, ' ', Keyword);
  108.             ProcessPattern := False;
  109.             Exit;
  110.           end;
  111.       end else begin
  112.         ProcessPattern := False;
  113.         Exit;
  114.       end
  115.     else
  116.     if Pattern [I] in [#4, #7] then begin
  117.       if (  (Upcase [Str [Pos + I - 1]] in ['B', 'C', 'D'])
  118.         and (Upcase [Str [Pos + I]] in ['X', 'L', 'H']))
  119.       or (  (Upcase [Str [Pos + I - 1]] in ['S', 'D'])
  120.         and (Upcase [Str [Pos + I]] = 'I'))
  121.       or (  (Upcase [Str [Pos + I - 1]] in ['B', 'S'])
  122.         and (Upcase [Str [Pos + I]] = 'P'))
  123.       or (  (Upcase [Str [Pos + I - 1]] in ['D', 'E', 'S', 'F', 'G'])
  124.         and (Upcase [Str [Pos + I]] = 'S'))
  125.       or (  (Upcase [Str [Pos + I - 1]] = 'S')
  126.         and (Upcase [Str [Pos + I]] = 'F'))
  127.       then begin
  128.         J := System. Pos (#4, Keyword);
  129.         if J > 0 then begin
  130.           Keyword [J] := Str [Pos + I - 1];
  131.           Keyword [J + 1] := Str [Pos + I];
  132.           Inc (I);
  133.         end else
  134.           if Pattern [I] = #4 then begin
  135.             WriteLn (Str);
  136.             WriteLn ('error in keyword pattern (2) ', Pattern, ' ', Keyword);
  137.             ProcessPattern := False;
  138.             Exit;
  139.           end else
  140.             Inc (I);
  141.       end else begin
  142.         ProcessPattern := False;
  143.         Exit;
  144.       end
  145.     end else
  146.     if Pattern [I] in [#5, #8] then begin
  147.       if (  (Upcase [Str [Pos + I - 1]] in ['B', 'C', 'D'])
  148.         and (Upcase [Str [Pos + I]] in ['X', 'L', 'H']))
  149.       or (  (Upcase [Str [Pos + I - 1]] = 'S')
  150.         and (Upcase [Str [Pos + I]] = 'F'))
  151.       then begin
  152.         J := System. Pos (#5, Keyword);
  153.         if J > 0 then begin
  154.           Keyword [J] := Str [Pos + I - 1];
  155.           Keyword [J + 1] := Str [Pos + I];
  156.           Inc (I);
  157.         end else
  158.           if Pattern [I] = #5 then begin
  159.             WriteLn (Str);
  160.             WriteLn ('error in keyword pattern (3) ', Pattern, ' ', Keyword);
  161.             ProcessPattern := False;
  162.             Exit;
  163.           end else
  164.             Inc (I);
  165.       end else begin
  166.         ProcessPattern := False;
  167.         Exit;
  168.       end
  169.     end else
  170.     if ((Pattern [I] = 'X') and (Upcase [Str [Pos + I - 1]] in ['L', 'H']))
  171.     or ((Pattern [I] in ['L', 'H']) and (Upcase [Str [Pos + I - 1]] = 'X'))
  172.     then
  173.       {Ok}
  174.     else
  175.     if Pattern [I] = 'H' then begin
  176.       if Upcase [Str [Pos + I - 1]] <> 'H' then begin
  177.         Delete (Pattern, I, 1);
  178.         Dec (I);
  179.       end;
  180.     end else
  181.     if Upcase [Str [Pos + I - 1]] <> Upcase [Pattern [I]] then begin
  182.       ProcessPattern := False;
  183.       Exit;
  184.     end;
  185.  
  186.     Inc (I);
  187.   end;
  188.  
  189.   {Once user's request for pattern with helper was confirmed}
  190.   {make the pattern suitable for helper string analizis.    }
  191.   if Pattern [Length (Pattern)] = '"' then
  192.     Dec (Pattern [0]);
  193.  
  194.   if  (Pos + Length (Pattern) - 1 > Length (Str))
  195.   and (Pattern [Length (Pattern)] in ['h', 'H']) then
  196.     Dec (Pattern [0]);
  197.  
  198.   if Pos + Length (Pattern) - 1 <= Length (Str) then begin
  199.     if (System. Pos (#3, Keyword) > 0)
  200.     or (System. Pos (#4, Keyword) > 0)
  201.     or (System. Pos (#5, Keyword) > 0) then begin
  202.       WriteLn (Str);
  203.       WriteLn ('error in keyword pattern (4) ', Pattern, ' ', Keyword);
  204.     end;
  205.  
  206.     if  (Length (Keyword) < 13)
  207.     and (Pos + Length (Pattern) <= Length (Str))
  208.     and (Str [Pos + Length (Pattern)] in (['/', 'h', 'H', ':', '-'] + HexChars))
  209.     and (Pos + Length (Pattern) + 1 <= Length (Str))
  210.     and (not (Str [Pos + Length (Pattern) + 1] in ['I', 'R', 'W', '-', ' ']))
  211.     then begin
  212.       WriteLn (IncompPattern, Str);
  213.       WriteLn (IncompPattern, 'not a complete pattern ', Pattern, ' for keyword ', Keyword);
  214.     end;
  215.  
  216.     if  (Pos + Length (Pattern) <= Length (Str))
  217.     and (Str [Pos + Length (Pattern)] = '"') then begin
  218.       Keyword := Keyword + '"';
  219.       I := Pos + Length (Pattern) + 1;
  220.       while (I <= Length (Str)) and (Str [I] <> '"') do begin
  221.         Keyword := Keyword + Str [I];
  222.         Inc (I);
  223.       end;
  224.       if I <= Length (Str) then begin
  225.         Keyword := Keyword + '"';
  226.         if Copy (Keyword, 1, 4) = 'INT ' then
  227.           Delete (Keyword, 1, 4);
  228.       end else
  229.         Delete (Keyword, System.Pos ('"', Keyword), Length (Keyword));
  230.     end;
  231.  
  232.     Topic^. AddKeyword (Keyword, StepBack);
  233.     Insert (#2, Str, Pos + Length (Pattern));
  234.     Insert (#2, Str, Pos);
  235.     Inc (Pos, Length (Pattern) + 1);
  236.  
  237.     ProcessPattern := True;
  238.   end else
  239.     ProcessPattern := False;
  240. end;
  241.  
  242. function SkipPattern (var Str: string; var Pos: Integer;
  243.                       Pattern: string): Boolean;
  244. var I, J: Integer;
  245. begin
  246.   I := 1;
  247.   while I <= Length (Pattern) do begin
  248.     if Pattern [I] = #3 then
  249.       if Upcase [Str [Pos + I - 1]] in HexChars + ['X'] then begin
  250.         {Ok}
  251.       end else begin
  252.         SkipPattern := False;
  253.         Exit;
  254.       end
  255.     else
  256.     if Pattern [I] = #4 then begin
  257.       if (  (Upcase [Str [Pos + I - 1]] in ['B', 'C', 'D'])
  258.         and (Upcase [Str [Pos + I]] in ['X', 'L', 'H']))
  259.       or (  (Upcase [Str [Pos + I - 1]] in ['S', 'D'])
  260.         and (Upcase [Str [Pos + I]] = 'I'))
  261.       or (  (Upcase [Str [Pos + I - 1]] in ['B', 'S'])
  262.         and (Upcase [Str [Pos + I]] = 'P'))
  263.       or (  (Upcase [Str [Pos + I - 1]] in ['D', 'E', 'S', 'F', 'G'])
  264.         and (Upcase [Str [Pos + I]] = 'S'))
  265.       or (  (Upcase [Str [Pos + I - 1]] = 'S')
  266.         and (Upcase [Str [Pos + I]] = 'F'))
  267.       then begin
  268.         {Ok}
  269.       end else begin
  270.         SkipPattern := False;
  271.         Exit;
  272.       end
  273.     end else
  274.     if Pattern [I] = #5 then begin
  275.       if (  (Upcase [Str [Pos + I - 1]] in ['B', 'C', 'D'])
  276.         and (Upcase [Str [Pos + I]] in ['X', 'L', 'H']))
  277.       or (  (Upcase [Str [Pos + I - 1]] = 'S')
  278.         and (Upcase [Str [Pos + I]] = 'F'))
  279.       then begin
  280.         {Ok}
  281.       end else begin
  282.         SkipPattern := False;
  283.         Exit;
  284.       end
  285.     end else
  286.     if ((Pattern [I] = 'X') and (Upcase [Str [Pos + I - 1]] in ['L', 'H']))
  287.     or ((Pattern [I] in ['L', 'H']) and (Upcase [Str [Pos + I - 1]] = 'X'))
  288.     then
  289.       {Ok}
  290.     else
  291.     if Pattern [I] = 'H' then begin
  292.       if Upcase [Str [Pos + I - 1]] <> 'H' then begin
  293.         Delete (Pattern, I, 1);
  294.         Dec (I);
  295.       end;
  296.     end else
  297.     if Upcase [Str [Pos + I - 1]] <> Upcase [Pattern [I]] then begin
  298.       SkipPattern := False;
  299.       Exit;
  300.     end;
  301.  
  302.     Inc (I);
  303.   end;
  304.  
  305.   if Pos + Length (Pattern) - 1 <= Length (Str) then begin
  306.     if  (Pos + Length (Pattern) <= Length (Str))
  307.     and (Str [Pos + Length (Pattern)] in (['/', 'h', 'H', ':', '-'] + HexChars))
  308.     and (Pos + Length (Pattern) + 1 <= Length (Str))
  309.     and (not (Str [Pos + Length (Pattern) + 1] in ['I', 'R', 'W', '-', ' ']))
  310.     then begin
  311.       WriteLn (IncompPattern, Str);
  312.       WriteLn (IncompPattern, 'not a complete pattern ', Pattern);
  313.     end;
  314.  
  315.     Inc (Pos, Length (Pattern) - 1);
  316.  
  317.     SkipPattern := True;
  318.   end else
  319.     SkipPattern := False;
  320. end;
  321.  
  322. procedure AddStr2Topic (Str: string; var Topic: PTopic;
  323.                         var TopicName: string; const CurInt, CurSubF, CurCat: string;
  324.                         Indexed: Boolean);
  325. var I: Integer;
  326.     KeyCnt: Integer;
  327. begin
  328.   KeyCnt := 0;
  329.   for I := 1 to Length (Str) do
  330.     if Str [I] = #2 then
  331.       Inc (KeyCnt);
  332.  
  333.   I := 1;
  334.   while I <= Length (Str) do begin
  335.     if Str [I] = #2 then
  336.       Dec (KeyCnt);
  337.  
  338.     if not Odd (KeyCnt) then
  339.       if  (I + 4 <= Length (Str))
  340.       and (Str [I] = '#')
  341.       and (Str [I + 1] in ['0'..'9', 'C', 'F', 'M', 'P'])
  342.       and (Str [I + 2] in ['0'..'9'])
  343.       and (Str [I + 3] in ['0'..'9'])
  344.       and (Str [I + 4] in ['0'..'9'])
  345.       then begin
  346.         Topic^. AddKeyword (Copy (Str, I, 5), KeyCnt div 2);
  347.         Insert (#2, Str, I + 5);
  348.         Insert (#2, Str, I);
  349.         Inc (I, 6);
  350.       end else
  351.         if (I = 1)
  352.         or (not (Upcase [Str [I - 1]] in ['A'..'Z', '0'..'9'])) then
  353.           case Upcase [Str [I]] of
  354.           'I':
  355.             if ProcessPattern (Str, I, 'INT '#3#3'H/AX='#3#3#3#3'H/'#4#4'='#3#3#3#3'H',
  356.                  #3#3#3#3#3#3#4#4#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  357.  
  358.             or ProcessPattern (Str, I, 'INT 13/AX=2000H/DL=81H', '1320' + CurCat, Topic, KeyCnt div 2)
  359.             or ProcessPattern (Str, I, 'INT '#3#3'H/AX='#3#3#3#3'H/'#5#5'='#3#3'H',
  360.                  #3#3#3#3#3#3#5#5#3#3 + CurCat, Topic, KeyCnt div 2)
  361.  
  362.             or ProcessPattern (Str, I, 'INT 21/AX=4202H/CX=0/DX=0', '2142' + CurCat, Topic, KeyCnt div 2)
  363.             or ProcessPattern (Str, I, 'INT '#3#3'H/AX='#6#6#6#6'H-'#6#6#6#6'H',
  364.                  'INT '#3#3, Topic, KeyCnt div 2)
  365.             or ProcessPattern (Str, I, 'INT '#3#3'H/AX='#3#3#3#3'H',
  366.                  #3#3#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  367.  
  368.             or ProcessPattern (Str, I, 'INT '#3#3'H/AH='#3#3#3#3'H',
  369.                  #3#3#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  370.  
  371.             or ProcessPattern (Str, I, 'INT '#3#3'H/AH='#3#3'H/'#4#4'='#3#3#3#3'H',
  372.                  #3#3#3#3'--'#4#4#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  373.             or ProcessPattern (Str, I, 'INT '#3#3'H/AH='#3#3'H/'#5#5'='#3#3'H',
  374.                  #3#3#3#3'--'#5#5#3#3 + CurCat, Topic, KeyCnt div 2)
  375.             or ProcessPattern (Str, I, 'INT '#3#3'H/AH='#6#6'H-'#6#6'H',
  376.                  'INT '#3#3, Topic, KeyCnt div 2)
  377.             or ProcessPattern (Str, I, 'INT '#3#3'H/AH='#3#3'H',
  378.                  #3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  379.  
  380.             or ProcessPattern (Str, I, 'INT '#3#3'H/AL='#3#3'H/'#4#4'='#3#3#3#3'H',
  381.                  #3#3'--'#3#3#4#4#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  382.             or ProcessPattern (Str, I, 'INT '#3#3'H/AL='#3#3'H/'#5#5'='#3#3'H',
  383.                  #3#3'--'#3#3#5#5#3#3 + CurCat, Topic, KeyCnt div 2)
  384.             or ProcessPattern (Str, I, 'INT '#3#3'H/AL='#3#3'H',
  385.                  #3#3'--'#3#3 + CurCat, Topic, KeyCnt div 2)
  386.  
  387.             or ProcessPattern (Str, I, 'INT '#3#3'H/'#4#4'='#3#3#3#3'H',
  388.                  #3#3'----'#4#4#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  389.             or ProcessPattern (Str, I, 'INT '#3#3'H/'#5#5'='#3#3'H',
  390.                  #3#3'----'#5#5#3#3 + CurCat, Topic, KeyCnt div 2)
  391.  
  392.             or ProcessPattern (Str, I, 'INT '#3#3'H/'#3#3#3#3'H',
  393.                  #3#3#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  394.             or ProcessPattern (Str, I, 'INT '#3#3'H/'#6#6'H-'#6#6'H',
  395.                  'INT '#3#3, Topic, KeyCnt div 2)
  396.             or ProcessPattern (Str, I, 'INT '#3#3'H/'#3#3'H',
  397.                  #3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  398.             or ProcessPattern (Str, I, 'INT '#6#6'-INT '#6#6'H',
  399.                  'TITLES', Topic, KeyCnt div 2)
  400.             or ProcessPattern (Str, I, 'INT '#6#6'-'#6#6'H',
  401.                  'TITLES', Topic, KeyCnt div 2)
  402.             or ProcessPattern (Str, I, 'INT XXH',
  403.                  'TITLES', Topic, KeyCnt div 2)
  404.             or ProcessPattern (Str, I, 'INT '#3#3'H',
  405.                  'INT '#3#3, Topic, KeyCnt div 2)
  406.             then
  407.               ;
  408.           'A':
  409.             if ProcessPattern (Str, I, 'AX='#3#3#3#3'H/'#4#4'='#3#3#3#3'H',
  410.                  CurInt + #3#3#3#3#4#4#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  411.             or ProcessPattern (Str, I, 'AX='#3#3#3#3'H/'#5#5'='#3#3'H',
  412.                  CurInt + #3#3#3#3#5#5#3#3 + CurCat, Topic, KeyCnt div 2)
  413.             or ProcessPattern (Str, I, 'AX='#6#6#6#6'H-'#6#6#6#6'H',
  414.                  'INT ' + CurInt, Topic, KeyCnt div 2)
  415.             or ProcessPattern (Str, I, 'AX='#3#3#3#3'H',
  416.                  CurInt + #3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  417.             or ProcessPattern (Str, I, 'AH='#3#3'H/AL='#3#3'H',
  418.                  CurInt + #3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  419.  
  420.             or ProcessPattern (Str, I, 'AH='#3#3'H/'#4#4'='#3#3#3#3'H',
  421.                  CurInt + #3#3'--'#4#4#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  422.             or ProcessPattern (Str, I, 'AH='#3#3'H/'#5#5'='#3#3'H',
  423.                  CurInt + #3#3'--'#5#5#3#3 + CurCat, Topic, KeyCnt div 2)
  424.             or ProcessPattern (Str, I, 'AH='#6#6'H-'#6#6'H',
  425.                  'INT ' + CurInt, Topic, KeyCnt div 2)
  426.             or ProcessPattern (Str, I, 'AH='#3#3'H',
  427.                  CurInt + #3#3 + CurCat, Topic, KeyCnt div 2)
  428.  
  429.             or ProcessPattern (Str, I, 'AL='#3#3'H/'#4#4'='#3#3#3#3'H',
  430.                  CurInt + Copy (CurSubF, 1, 2) + #3#3#4#4#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  431.             or ProcessPattern (Str, I, 'AL='#3#3'H/'#5#5'='#3#3'H',
  432.                  CurInt + Copy (CurSubF, 1, 2) + #3#3#5#5#3#3 + CurCat, Topic, KeyCnt div 2)
  433.             or ProcessPattern (Str, I, 'AL='#6#6'H/'#6#6'H',
  434.                  CurInt + Copy (CurSubF, 1, 2) + CurCat, Topic, KeyCnt div 2)
  435.             or ProcessPattern (Str, I, 'AL='#6#6'H-'#6#6'H',
  436.                  CurInt + Copy (CurSubF, 1, 2) + CurCat, Topic, KeyCnt div 2)
  437.             or ProcessPattern (Str, I, 'AL='#3#3'H',
  438.                  CurInt + Copy (CurSubF, 1, 2) + #3#3 + CurCat, Topic, KeyCnt div 2)
  439.             then
  440.               ;
  441.           'B', 'C', 'D', 'S', 'E', 'F', 'G':
  442.             if ProcessPattern (Str, I, #4#4'='#3#3#3#3'H',
  443.                  CurInt + CurSubF + #4#4#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  444.             or SkipPattern (Str, I, 'CX=CX-1')
  445.             or ProcessPattern (Str, I, #8#8'='#6#6'H/'#6#6'H',
  446.                  CurInt + CurSubF + CurCat, Topic, KeyCnt div 2)
  447.             or ProcessPattern (Str, I, #8#8'='#6#6'H-'#6#6'H',
  448.                  CurInt + CurSubF + CurCat, Topic, KeyCnt div 2)
  449.             or ProcessPattern (Str, I, #5#5'='#3#3'H',
  450.                  CurInt + CurSubF + #5#5#3#3 + CurCat, Topic, KeyCnt div 2)
  451.             then
  452.               {nothing}
  453.             else
  454.             if Upcase [Str [I]] = 'C' then begin
  455.               if ProcessPattern (Str, I, 'CMOS DATA',
  456.                    'CMOS', Topic, KeyCnt div 2)
  457.               or ProcessPattern (Str, I, 'CMOS 8086/88',
  458.                    'CMOS', Topic, KeyCnt div 2)
  459.               or ProcessPattern (Str, I, 'CMOS 80C86/88',
  460.                    'CMOS', Topic, KeyCnt div 2)
  461.               or ProcessPattern (Str, I, 'CMOS '#3#3#3#3'H',
  462.                    'R'#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  463.               or ProcessPattern (Str, I, 'CMOS '#3#3'H-'#3#3'H',
  464.                    'R'#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  465.               or ProcessPattern (Str, I, 'CMOS '#3#3'H',
  466.                    'R'#3#3 + CurCat, Topic, KeyCnt div 2)
  467.               or ProcessPattern (Str, I, 'CMOS',
  468.                    'CMOS', Topic, KeyCnt div 2)
  469.  
  470.               or ProcessPattern (Str, I, 'CALL XXXXH:XXXXH"',
  471.                    '@xxxxxxxx', Topic, KeyCnt div 2)
  472.               or ProcessPattern (Str, I, 'CALL XXXXH:XXXXH',
  473.                    'FAR CALLS', Topic, KeyCnt div 2)
  474.               or ProcessPattern (Str, I, 'CALL '#3#3#3#3'H:'#3#3#3#3'H',
  475.                  '@'#3#3#3#3#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  476.               then
  477.                 ;
  478.             end;
  479.           '@':
  480.             if ProcessPattern (Str, I, '@XXXXH:XXXXH"',
  481.                  '@xxxxxxxx', Topic, KeyCnt div 2)
  482.             or ProcessPattern (Str, I, '@XXXXH:XXXXH',
  483.                  'FAR CALLS', Topic, KeyCnt div 2)
  484.             or ProcessPattern (Str, I, '@'#3#3#3#3'H:'#3#3#3#3'H',
  485.                  '@'#3#3#3#3#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  486.             then
  487.               ;
  488.           'M':
  489.             if ProcessPattern (Str, I, 'MEM '#6#6#6#6'H:xxxxH',
  490.                  'MEMORY', Topic, KeyCnt div 2)
  491.             or ProcessPattern (Str, I, 'MEM '#3#3#3#3'H:'#3#3#3#3'H',
  492.                  'M'#3#3#3#3#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  493.             or ProcessPattern (Str, I, 'MEM '#3#3#3#3#3#3#3#3'H',
  494.                  'M'#3#3#3#3#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  495.             then
  496.               ;
  497.           'P':
  498.             if ProcessPattern (Str, I, 'PORT ACCESS',
  499.                  'PORTS', Topic, KeyCnt div 2)
  500.             or ProcessPattern (Str, I, 'PORT '#3#3#3#3'H-'#3#3#3#3'H',
  501.                  'P'#3#3#3#3#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  502.             or ProcessPattern (Str, I, 'PORT '#3#3#3#3'H-'#3#3#3'H',
  503.                  'P'#3#3#3#3#3#3#3' ' + CurCat, Topic, KeyCnt div 2)
  504.             or ProcessPattern (Str, I, 'PORT '#3#3#3#3'H-????H',
  505.                  'P'#3#3#3#3'????' + CurCat, Topic, KeyCnt div 2)
  506.             or ProcessPattern (Str, I, 'PORT '#3#3#3#3'H',
  507.                  'P'#3#3#3#3 + CurCat, Topic, KeyCnt div 2)
  508.             then
  509.               ;
  510.           end;
  511.  
  512.     Inc (I);
  513.   end;
  514.  
  515.   Topic^. AddString (' ' + Str);
  516. end;
  517.  
  518. function NoLinks (S: string): string;
  519. var I: Integer;
  520. begin
  521.   I := Pos (#2, S);
  522.   while I > 0 do begin
  523.     Delete (S, I, 1);
  524.     I := Pos (#2, S);
  525.   end;
  526.   NoLinks := S;
  527. end;
  528.  
  529. procedure Tab2Spc (var Str: string);
  530. var I, J: Integer;
  531. begin
  532.   I := Pos (#9, Str);
  533.   while I > 0 do begin
  534.     Delete (Str, I, 1);
  535.     for J := 7 downto ((I - 1) mod 8) do
  536.       Insert (' ', Str, I);
  537.     I := Pos (#9, Str);
  538.   end;
  539. end;
  540.  
  541. function ProcessInterrup (const FileName: string; const FileIsATopic: string): Boolean;
  542. type
  543.   DividerRec = record
  544.     Len: Byte;
  545.     S: array [0..7] of Char;   (* '--------' *)
  546.     Cat: Char;                 (* category *)
  547.     C: Char;                   (* '-' *)
  548.     case Integer of
  549.       0: (Int: array [0..1] of Char; (* Interrupt number, 2 hex digits *)
  550.           SubF: array [0..3] of Char;(* sub function, 4 hex digits or '-' *)
  551.           R: array [0..1] of Char;   (* Secondary Register Name, Two Letters or '--' *)
  552.           RV: array [0..3] of Char;  (* sec. reg. value, 4 hex digits or '-' *)
  553.           Rest: array [0..17] of Char;
  554.          );
  555.       1: (RSign: Char;
  556.           R1,
  557.           R2: array [0..1] of Char;
  558.          );
  559.       2: (AtSign: Char;
  560.           CallSeg,
  561.           CallOfs: array [0..3] of Char;
  562.          );
  563.       3: (MSign: Char;
  564.           MemSeg,
  565.           MemOfs: array [0..3] of Char;
  566.          );
  567.       4: (PSign: Char;
  568.           P1,
  569.           P2: array [0..3] of Char;
  570.          );
  571.   end;            (* record dividerRec *)
  572.  
  573.   T2W = record Lo, Hi: Word; end;
  574.   T22 = record Lo, Hi: array [0..1] of Char; end;
  575.  
  576. var
  577.   FI: Text;
  578.   Str, StrUp: string;
  579.   TopicName: string;
  580.  
  581.   CurCat: string [1];
  582.   CurInt: string [2];
  583.   CurSubF: string [4];
  584.  
  585.   DR: DividerRec absolute Str;
  586.  
  587. procedure ProcessHdr (Hdr: string);
  588. begin
  589.   with DR do begin
  590.     if (S <> '--------')
  591.     or (not (Cat in ['A'..'Z', 'a'..'z', '!', '*', '-']))
  592.     or (C <> '-')
  593.     or ((Cat <> '!')
  594.         and
  595.         ((not (RSign in ['R', 'r']))
  596.       or (not (R1 [0] in HexChars))
  597.       or (not (R1 [1] in HexChars))
  598.       or (  (R2 <> '--')
  599.         and ((not (R2 [0] in HexChars))
  600.           or (not (R2 [1] in HexChars)))
  601.          )
  602.         )
  603.         and
  604.         ((not (AtSign = '@'))
  605.       or (not (CallSeg [0] in HexChars + ['x']))
  606.       or (not (CallSeg [1] in HexChars + ['x']))
  607.       or (not (CallSeg [2] in HexChars + ['x']))
  608.       or (not (CallSeg [3] in HexChars + ['x']))
  609.       or (not (CallOfs [0] in HexChars + ['x']))
  610.       or (not (CallOfs [1] in HexChars + ['x']))
  611.       or (not (CallOfs [2] in HexChars + ['x']))
  612.       or (not (CallOfs [3] in HexChars + ['x']))
  613.         )
  614.         and
  615.         ((not (MSign in ['M', 'm']))
  616.       or (not (MemSeg [0] in HexChars + ['x']))
  617.       or (not (MemSeg [1] in HexChars + ['x']))
  618.       or (not (MemSeg [2] in HexChars + ['x']))
  619.       or (not (MemSeg [3] in HexChars + ['x']))
  620.       or (not (MemOfs [0] in HexChars + ['x']))
  621.       or (not (MemOfs [1] in HexChars + ['x']))
  622.       or (not (MemOfs [2] in HexChars + ['x']))
  623.       or (not (MemOfs [3] in HexChars + ['x']))
  624.         )
  625.         and
  626.         ((not (PSign in ['P', 'p']))
  627.       or (not (P1 [0] in HexChars))
  628.       or (not (P1 [1] in HexChars))
  629.       or (not (P1 [2] in HexChars))
  630.       or (not (P1 [3] in HexChars))
  631.       or (  (P2 <> '----')
  632.         and (P2 <> '????')
  633.         and ((not (P2 [0] in HexChars))
  634.           or (not (P2 [1] in HexChars))
  635.           or (not (P2 [2] in HexChars))
  636.           or (not (P2 [3] in HexChars + ['x', ' '])))
  637.          )
  638.         )
  639.         and
  640.         ((not (Int [0] in HexChars))
  641.       or (not (Int [1] in HexChars))
  642.       or (  (SubF <> '----')
  643.         and ((T22 (SubF). Lo <> '--')
  644.           or (not (SubF [2] in HexChars))
  645.           or (not (SubF [3] in HexChars)))
  646.         and ((T22 (SubF). Hi <> '--')
  647.           or (not (SubF [0] in HexChars))
  648.           or (not (SubF [1] in HexChars)))
  649.         and ((not (SubF [0] in HexChars))
  650.           or (not (SubF [1] in HexChars))
  651.           or (not (SubF [2] in HexChars))
  652.           or (not (SubF [3] in HexChars)))
  653.          )
  654.       or (  (R <> '--')
  655.         and ((R <> 'BX') or (not (RV [0] in HexChars))
  656.                          or (not (RV [1] in HexChars))
  657.                          or (not (RV [2] in HexChars))
  658.                          or (not (RV [3] in HexChars)))
  659.         and ((R <> 'CX') or (not (RV [0] in HexChars))
  660.                          or (not (RV [1] in HexChars))
  661.                          or (not (RV [2] in HexChars))
  662.                          or (not (RV [3] in HexChars)))
  663.         and ((R <> 'DX') or (not (RV [0] in HexChars))
  664.                          or (not (RV [1] in HexChars))
  665.                          or (not (RV [2] in HexChars))
  666.                          or (not (RV [3] in HexChars)))
  667.         and ((R <> 'SI') or (not (RV [0] in HexChars))
  668.                          or (not (RV [1] in HexChars))
  669.                          or (not (RV [2] in HexChars))
  670.                          or (not (RV [3] in HexChars)))
  671.         and ((R <> 'DI') or (not (RV [0] in HexChars))
  672.                          or (not (RV [1] in HexChars))
  673.                          or (not (RV [2] in HexChars))
  674.                          or (not (RV [3] in HexChars)))
  675.         and ((R <> 'SP') or (not (RV [0] in HexChars))
  676.                          or (not (RV [1] in HexChars))
  677.                          or (not (RV [2] in HexChars))
  678.                          or (not (RV [3] in HexChars)))
  679.         and ((R <> 'BP') or (not (RV [0] in HexChars))
  680.                          or (not (RV [1] in HexChars))
  681.                          or (not (RV [2] in HexChars))
  682.                          or (not (RV [3] in HexChars)))
  683.         and ((R <> 'ES') or (not (RV [0] in HexChars))
  684.                          or (not (RV [1] in HexChars))
  685.                          or (not (RV [2] in HexChars))
  686.                          or (not (RV [3] in HexChars)))
  687.         and ((R <> 'DS') or (not (RV [0] in HexChars))
  688.                          or (not (RV [1] in HexChars))
  689.                          or (not (RV [2] in HexChars))
  690.                          or (not (RV [3] in HexChars)))
  691.  
  692.         and ((R <> 'BH') or (not (RV [0] in HexChars))
  693.                          or (not (RV [1] in HexChars))
  694.                          or (T22 (RV). Hi <> '--'))
  695.         and ((R <> 'BL') or (not (RV [0] in HexChars))
  696.                          or (not (RV [1] in HexChars))
  697.                          or (T22 (RV). Hi <> '--'))
  698.         and ((R <> 'CH') or (not (RV [0] in HexChars))
  699.                          or (not (RV [1] in HexChars))
  700.                          or (T22 (RV). Hi <> '--'))
  701.         and ((R <> 'CL') or (not (RV [0] in HexChars))
  702.                          or (not (RV [1] in HexChars))
  703.                          or (T22 (RV). Hi <> '--'))
  704.         and ((R <> 'DH') or (not (RV [0] in HexChars))
  705.                          or (not (RV [1] in HexChars))
  706.                          or (T22 (RV). Hi <> '--'))
  707.         and ((R <> 'DL') or (not (RV [0] in HexChars))
  708.                          or (not (RV [1] in HexChars))
  709.                          or (T22 (RV). Hi <> '--'))
  710.  
  711.         and ((R <> 'SF') or (not (RV [0] in HexChars))
  712.                          or (not (RV [1] in HexChars))
  713.                          or (not (RV [2] in HexChars))
  714.                          or (not (RV [3] in HexChars)))
  715.         and ((R <> 'SF') or (not (RV [0] in HexChars))
  716.                          or (not (RV [1] in HexChars))
  717.                          or (T22 (RV). Hi <> '--'))
  718.          )
  719.       or (Rest <> '------------------')
  720.         )
  721.        )
  722.     then
  723.       WriteLn ('header error: ', Hdr);
  724.  
  725.     if Cat = '!' then begin
  726.       TopicName := Copy (Str, 10, Length (Str) - 9);
  727.       CurInt := '';
  728.       CurSubF := '';
  729.     end else
  730.       if RSign in ['R', 'r'] then begin
  731.         TopicName := RSign + R1 + R2;
  732.         CurInt := '';
  733.         CurSubF := '';
  734.       end else
  735.       if AtSign = '@' then begin
  736.         TopicName := AtSign + CallSeg + CallOfs;
  737.         CurInt := '';
  738.         CurSubF := '';
  739.       end else
  740.       if MSign in ['M', 'm'] then begin
  741.         TopicName := MSign + MemSeg + MemOfs;
  742.         CurInt := '';
  743.         CurSubF := '';
  744.       end else
  745.       if PSign in ['P', 'p'] then begin
  746.         TopicName := PSign + P1 + P2;
  747.         CurInt := '';
  748.         CurSubF := '';
  749.       end else begin
  750.         TopicName := Int + SubF + R + RV;
  751.         CurInt := Int;
  752.         CurSubF := SubF;
  753.       end;
  754.  
  755.     while TopicName [Length (TopicName)] = '-' do Dec (TopicName [0]);
  756.     if Length (TopicName) > 0 then
  757.       while TopicName [1] = '-' do Delete (TopicName, 1, 1)
  758.     else
  759.       TopicName := FileName;
  760.  
  761.     if not (Cat in ['!', '-']) then begin
  762.       TopicName := TopicName + Cat;
  763.       CurCat := Cat;
  764.     end else
  765.       CurCat := '';
  766.   end;
  767. end;
  768.  
  769. var
  770.   SectionStarted: Boolean;
  771.   SectionClosed: Boolean;
  772.   I, J: Integer;
  773.   Topic: PTopic;
  774.   ExtendedHeader: string;
  775.   OriginalTopicName: string;
  776.  
  777.   TblStarted: Boolean;
  778.   TblClosed: Boolean;
  779.   TblTopic: PTopic;
  780.   TblTopicName: string;
  781.  
  782.   PrevStr, SavePtr: PString;
  783.   AddNextStringToTopicAsATblRef: Boolean;
  784.  
  785. begin
  786.   Assign (FI, FileName);
  787.   {$I-}
  788.   Reset (FI);
  789.   if IOResult = 0 then begin
  790.     ProcessInterrup := True;
  791.     WriteLn ('processing ', FileName, '                                      ');
  792.  
  793.     TblStarted := False;
  794.     TblClosed := True;
  795.  
  796.     SectionStarted := False;
  797.     SectionClosed := True;
  798.  
  799.     AddNextStringToTopicAsATblRef := False;
  800.  
  801.     if FileIsATopic <> '' then begin
  802.       TopicName := FileIsATopic;
  803.       CurCat := '';
  804.       CurInt := '';
  805.       CurSubF := '';
  806.  
  807.       New (Topic, Init (1, 1));
  808.       SectionStarted := True;
  809.       SectionClosed := False;
  810.       TopicName := MakeCorrectTopicName (TopicName);
  811.       OriginalTopicName := TopicName;
  812.       ExtendedHeader := #2 + TopicName + #2;
  813.     end;
  814.  
  815.     while not EOF (FI) do begin
  816.       ReadLn (FI, Str);
  817.  
  818.       if  (Length (Str) > 0)
  819.       and (FileIsATopic = '')
  820.       and ((Str [1] = '-') and (Pos ('--------', Str) <> 0))
  821.       and (Str <> '---------------------------------------------')
  822.       and (Str <> '------------------------------------------------------------------------------')
  823.       then begin
  824.         if not TblClosed then begin
  825.           TblTopic^.AddKeywordAtStart (OriginalTopicName);
  826.           TblTopic^.SetSubHeader (ExtendedHeader);
  827.           FO. IdxTbl. Insert (New (PIndexEntry, Init (
  828.             TblTopicName, 0, TblTopic)));
  829.           TblStarted := False;
  830.           TblClosed := True;
  831.         end;
  832.  
  833.         if not SectionClosed then begin
  834.           if Pos ('CMOS', StUpcase2 (FileName)) > 0 then begin
  835.             CMOS^.AddKeyword (OriginalTopicName, 0);
  836.             AddStr2Topic (ExtendedHeader,
  837.                           CMOS, CMOSName, CurInt, CurSubF, CurCat, True);
  838.           end else
  839.           if Pos ('FARCALL', StUpcase2 (FileName)) > 0 then begin
  840.             FarCall^.AddKeyword (OriginalTopicName, 0);
  841.             AddStr2Topic (ExtendedHeader,
  842.                           FarCall, FarCallName, CurInt, CurSubF, CurCat, True);
  843.           end else
  844.           if Pos ('MEMORY', StUpcase2 (FileName)) > 0 then begin
  845.             Memory^.AddKeyword (OriginalTopicName, 0);
  846.             AddStr2Topic (ExtendedHeader,
  847.                           Memory, MemoryName, CurInt, CurSubF, CurCat, True);
  848.           end else
  849.           if Pos ('PORTS', StUpcase2 (FileName)) > 0 then begin
  850.             Ports^.AddKeyword (OriginalTopicName, 0);
  851.             AddStr2Topic (ExtendedHeader,
  852.                           Ports, PortsName, CurInt, CurSubF, CurCat, True);
  853.           end else
  854.           if  (FileIsATopic = '')
  855.           and ((not (ExtendedHeader [2] in HexChars))
  856.             or (not (ExtendedHeader [3] in HexChars)))
  857.           then begin
  858.             IntList^.AddKeyword (OriginalTopicName, 0);
  859.             AddStr2Topic (ExtendedHeader,
  860.                           IntList, IntListName, CurInt, CurSubF, CurCat, True);
  861.           end;
  862.  
  863.           Topic^.SetHeader (NoLinks (ExtendedHeader));
  864.           FO. IdxTbl. Insert (New (PIndexEntry, Init (
  865.             TopicName, 0, Topic)));
  866.           SectionClosed := True;
  867.         end;
  868.  
  869.         ProcessHdr (Str);
  870.  
  871.         if (StUpcase2 (TopicName) <> 'SECTION') then begin
  872.           New (Topic, Init (1, 1));
  873.           SectionStarted := True;
  874.           SectionClosed := False;
  875.           TopicName := MakeCorrectTopicName (TopicName);
  876.           OriginalTopicName := TopicName;
  877.           ExtendedHeader := #2 + TopicName + #2;
  878.           Write (TopicName: 31, ' mem - ', MaxAvail: 8, #13);
  879.         end else
  880.           SectionStarted := False;
  881.       end else begin
  882.         if SectionStarted then begin
  883.           Tab2Spc (Str);
  884.  
  885.           StrUp := StUpcase2 (Str);
  886.  
  887.           if  (Copy (StrUp, 1, 4) = 'INT ')
  888.           and (StrUp [5] in HexChars) and (StrUp [6] in HexChars)
  889.           and (Pos ('INT', StUpcase2 (FileName)) > 0) then begin
  890.             I := (Pos (StrUp [5], HexCh) - 1)*16 + Pos (StrUp [6], HexCh) - 1;
  891.             IntLists [I]^.AddKeyword (OriginalTopicName, 0);
  892.             ExtendedHeader := #2 + TopicName + #2
  893.                             + Copy (Str, 7, Length (Str) - 6);
  894.             AddStr2Topic (ExtendedHeader,
  895.                           IntLists [I], string (Pointer(@IntNames [I])^), CurInt, CurSubF, CurCat, True);
  896.           end;
  897.  
  898.           if  (Copy (StrUp, 1, 5) = 'CMOS ')
  899.           and (StrUp [6] in HexChars) and (StrUp [7] in HexChars)
  900.           and (StrUp [8] = 'H') then begin
  901.             if  (StrUp [9] = '-')
  902.             and (StrUp [10] in HexChars) and (StrUp [11] in HexChars)
  903.             and (StrUp [12] = 'H') then
  904.               ExtendedHeader := Copy (Str, 13, Length (Str) - 12)
  905.             else
  906.               ExtendedHeader := Copy (Str, 9, Length (Str) - 8);
  907.  
  908.             ExtendedHeader := #2 + TopicName + #2 + ExtendedHeader;
  909.           end;
  910.  
  911.           if  (Copy (StrUp, 1, 5) = 'CALL ')
  912.           and (StrUp [6] in HexChars + ['X']) and (StrUp [7] in HexChars + ['X'])
  913.           and (StrUp [8] in HexChars + ['X']) and (StrUp [9] in HexChars + ['X'])
  914.           and (StrUp [10] = 'H')
  915.           and (StrUp [11] = ':')
  916.           and (StrUp [12] in HexChars + ['X']) and (StrUp [13] in HexChars + ['X'])
  917.           and (StrUp [14] in HexChars + ['X']) and (StrUp [15] in HexChars + ['X'])
  918.           and (StrUp [16] = 'H')
  919.           then begin
  920.             ExtendedHeader := #2 + TopicName + #2
  921.                             + Copy (Str, 17, Length (Str) - 16);
  922.           end;
  923.  
  924.           if  (Copy (StrUp, 1, 4) = 'MEM ')
  925.           and (StrUp [5] in HexChars + ['X']) and (StrUp [6] in HexChars + ['X'])
  926.           and (StrUp [7] in HexChars + ['X']) and (StrUp [8] in HexChars + ['X'])
  927.           then
  928.             if  (StrUp [9] = 'H')
  929.             and (StrUp [10] = ':')
  930.             and (StrUp [11] in HexChars + ['X']) and (StrUp [12] in HexChars + ['X'])
  931.             and (StrUp [13] in HexChars + ['X']) and (StrUp [14] in HexChars + ['X'])
  932.             and (StrUp [15] = 'H')
  933.             then
  934.               ExtendedHeader := #2 + TopicName + #2
  935.                               + Copy (Str, 16, Length (Str) - 15)
  936.             else
  937.             if  (StrUp  [9] in HexChars + ['X']) and (StrUp [10] in HexChars + ['X'])
  938.             and (StrUp [11] in HexChars + ['X']) and (StrUp [12] in HexChars + ['X'])
  939.             and (StrUp [13] = 'H')
  940.             then
  941.               ExtendedHeader := #2 + TopicName + #2
  942.                               + Copy (Str, 14, Length (Str) - 13);
  943.  
  944.           if  (Copy (StrUp, 1, 5) = 'PORT ')
  945.           and (StrUp [6] in HexChars) and (StrUp [7] in HexChars)
  946.           and (StrUp [8] in HexChars) and (StrUp [9] in HexChars)
  947.           then begin
  948.             if  (StrUp [10] = '-')
  949.             and (StrUp [11] in HexChars + ['?']) and (StrUp [12] in HexChars + ['?'])
  950.             and (StrUp [13] in HexChars + ['?']) and (StrUp [14] in HexChars + ['?', 'x', ' '])
  951.             then
  952.               ExtendedHeader := Copy (Str, 15, Length (Str) - 14)
  953.             else
  954.               ExtendedHeader := Copy (Str, 10, Length (Str) - 9);
  955.  
  956.             ExtendedHeader := #2 + TopicName + #2 + ExtendedHeader;
  957.           end;
  958.  
  959.           if KeyNames. Count > 0 then
  960.             for I := 0 to KeyNames. Count - 1 do begin
  961.               J := Pos (StUpcase2 (PString (KeyNames. At (I))^), StrUp);
  962.               if  (J > 0)
  963.               and ((PTopic (KeyLists. At (I))^. Count = 0)
  964.                 or (PString (PTopic (KeyLists. At (I))^. At (
  965.                     PTopic (KeyLists. At (I))^. Count - 1))^
  966.                  <> ' ' + ExtendedHeader))
  967.               then begin
  968.                 PTopic (KeyLists. Items^ [I])^.AddKeyword (OriginalTopicName, 0);
  969.                 AddStr2Topic (ExtendedHeader,
  970.                               PTopic (KeyLists. Items^ [I]),
  971.                               PString (KeyNames. At (I))^, CurInt, CurSubF, CurCat, True);
  972.               end;
  973.             end;
  974.  
  975.           I := Pos ('TABLE', StrUp);
  976.           if  (I > 0) and (I + 9 <= Length (Str))
  977.           and (Str [I + 6] in ['0'..'9', 'C', 'F', 'M', 'P'])
  978.           and (Str [I + 7] in ['0'..'9'])
  979.           and (Str [I + 8] in ['0'..'9'])
  980.           and (Str [I + 9] in ['0'..'9'])
  981.           then begin
  982.             if not TblClosed then begin
  983.               PrevStr := TblTopic^.At (TblTopic^.Count - 1);
  984.               if (PrevStr <> nil) and (PrevStr^ <> '') and (PrevStr^ <> ' ') then begin
  985.                 TblTopic^. AtDelete (TblTopic^.Count - 1);
  986.                 if PrevStr <> nil then begin
  987.                   J := Pos (#2, PrevStr^);
  988.                   while J > 0 do begin
  989.                     SavePtr := PrevStr;
  990.                     PrevStr := NewStr (Copy (PrevStr^, 1, J - 1)
  991.                                + Copy (PrevStr^, J + 1, Length (PrevStr^) - J));
  992.                     DisposeStr (SavePtr);
  993.                     J := Pos (#2, PrevStr^);
  994.                     if J = 0 then
  995.                       WriteLn ('error 5');
  996.                     SavePtr := PrevStr;
  997.                     PrevStr := NewStr (Copy (PrevStr^, 1, J - 1)
  998.                                + Copy (PrevStr^, J + 1, Length (PrevStr^) - J));
  999.                     DisposeStr (SavePtr);
  1000.                     TblTopic^. Keywords. AtFree (TblTopic^. Keywords. Count - 1);
  1001.                     J := Pos (#2, PrevStr^);
  1002.                   end;
  1003.                 end;
  1004.               end else
  1005.                 PrevStr := nil;
  1006.  
  1007.               TblTopic^.AddKeywordAtStart (OriginalTopicName);
  1008.               TblTopic^.SetSubHeader (ExtendedHeader);
  1009.               FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1010.                 TblTopicName, 0, TblTopic)));
  1011.               TblStarted := False;
  1012.               TblClosed := True;
  1013.             end else begin
  1014.               PrevStr := Topic^.At (Topic^.Count - 1);
  1015.               if (PrevStr <> nil) and (PrevStr^ <> '') and (PrevStr^ <> ' ') then begin
  1016.                 Topic^. AtDelete (Topic^.Count - 1);
  1017.                 if PrevStr <> nil then begin
  1018.                   J := Pos (#2, PrevStr^);
  1019.                   while J > 0 do begin
  1020.                     SavePtr := PrevStr;
  1021.                     PrevStr := NewStr (Copy (PrevStr^, 1, J - 1)
  1022.                                + Copy (PrevStr^, J + 1, Length (PrevStr^) - J));
  1023.                     DisposeStr (SavePtr);
  1024.                     J := Pos (#2, PrevStr^);
  1025.                     if J = 0 then
  1026.                       WriteLn ('error 5');
  1027.                     SavePtr := PrevStr;
  1028.                     PrevStr := NewStr (Copy (PrevStr^, 1, J - 1)
  1029.                                + Copy (PrevStr^, J + 1, Length (PrevStr^) - J));
  1030.                     DisposeStr (SavePtr);
  1031.                     Topic^. Keywords. AtFree (Topic^. Keywords. Count - 1);
  1032.                     J := Pos (#2, PrevStr^);
  1033.                   end;
  1034.                 end;
  1035.               end else
  1036.                 PrevStr := nil;
  1037.             end;
  1038.  
  1039.             New (TblTopic, Init (1, 1));
  1040.             TblStarted := True;
  1041.             TblClosed := False;
  1042.             TblTopicName := MakeCorrectTopicName ('#' + Copy (Str, I + 6, 4));
  1043.  
  1044.             if (PrevStr <> nil) and (PrevStr^ <> '') and (PrevStr^ <> ' ')
  1045.             then begin
  1046.               if Pos (#2, PrevStr^) > 0 then begin
  1047.                 WriteLn (PrevStr^);
  1048.                 WriteLn ('error 4');
  1049.               end;
  1050.               AddStr2Topic (PrevStr^, TblTopic, TblTopicName, CurInt, CurSubF, CurCat, False);
  1051.  
  1052.               AddStr2Topic (TblTopicName + PrevStr^, Topic, TopicName, CurInt, CurSubF, CurCat, True);
  1053.               TblTopic^.SetHeader (PrevStr^);
  1054.               Tables^.AddKeyword (TopicName, 0);
  1055.               AddStr2Topic (TblTopicName + ' '#2 + TopicName + #2
  1056.                           + PrevStr^, Tables, TablesName, CurInt, CurSubF, CurCat, True);
  1057.             end else
  1058.               AddNextStringToTopicAsATblRef := True;
  1059.             DisposeStr (PrevStr);
  1060.  
  1061.             AddStr2Topic (Str, TblTopic, TblTopicName, CurInt, CurSubF, CurCat, False);
  1062.           end else begin
  1063.             if TblStarted then begin
  1064.               if AddNextStringToTopicAsATblRef then begin
  1065.                 AddStr2Topic (TblTopicName + ' ' + Str, Topic, TopicName, CurInt, CurSubF, CurCat, True);
  1066.                 TblTopic^.SetHeader (Str);
  1067.                 Tables^.AddKeyword (TopicName, 0);
  1068.                 AddStr2Topic (TblTopicName + ' '#2 + TopicName + #2
  1069.                             + ' ' + Str, Tables, TablesName, CurInt, CurSubF, CurCat, True);
  1070.                 AddNextStringToTopicAsATblRef := False;
  1071.               end;
  1072.  
  1073.               AddStr2Topic (Str, TblTopic, TblTopicName, CurInt, CurSubF, CurCat, False);
  1074.             end;
  1075.           end;
  1076.  
  1077.           if not TblStarted then
  1078.             AddStr2Topic (Str, Topic, TopicName, CurInt, CurSubF, CurCat, True);
  1079.         end;
  1080.       end;
  1081.     end;
  1082.  
  1083.     if not TblClosed then begin
  1084.       TblTopic^.AddKeywordAtStart (OriginalTopicName);
  1085.       TblTopic^.SetSubHeader (ExtendedHeader);
  1086.       FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1087.         TblTopicName, 0, TblTopic)));
  1088.       TblStarted := False;
  1089.       TblClosed := True;
  1090.     end;
  1091.  
  1092.     if not SectionClosed then begin
  1093.       if Pos ('CMOS', StUpcase2 (FileName)) > 0 then begin
  1094.         CMOS^.AddKeyword (OriginalTopicName, 0);
  1095.         AddStr2Topic (ExtendedHeader,
  1096.                       CMOS, CMOSName, CurInt, CurSubF, CurCat, True);
  1097.       end else
  1098.       if Pos ('FARCALL', StUpcase2 (FileName)) > 0 then begin
  1099.         FarCall^.AddKeyword (OriginalTopicName, 0);
  1100.         AddStr2Topic (ExtendedHeader,
  1101.                       FarCall, FarCallName, CurInt, CurSubF, CurCat, True);
  1102.       end else
  1103.       if Pos ('MEMORY', StUpcase2 (FileName)) > 0 then begin
  1104.         Memory^.AddKeyword (OriginalTopicName, 0);
  1105.         AddStr2Topic (ExtendedHeader,
  1106.                       Memory, MemoryName, CurInt, CurSubF, CurCat, True);
  1107.       end else
  1108.       if Pos ('PORTS', StUpcase2 (FileName)) > 0 then begin
  1109.         Ports^.AddKeyword (OriginalTopicName, 0);
  1110.         AddStr2Topic (ExtendedHeader,
  1111.                       Ports, PortsName, CurInt, CurSubF, CurCat, True);
  1112.       end else
  1113.       if  (FileIsATopic = '')
  1114.       and ((not (ExtendedHeader [2] in HexChars))
  1115.         or (not (ExtendedHeader [3] in HexChars)))
  1116.       then begin
  1117.         IntList^.AddKeyword (OriginalTopicName, 0);
  1118.         AddStr2Topic (ExtendedHeader,
  1119.                       IntList, IntListName, CurInt, CurSubF, CurCat, True);
  1120.       end;
  1121.  
  1122.       Topic^.SetHeader (NoLinks (ExtendedHeader));
  1123.       FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1124.         TopicName, 0, Topic)));
  1125.       SectionClosed := True;
  1126.     end;
  1127.  
  1128.     Close (FI);
  1129.   end else
  1130.     ProcessInterrup := False;
  1131. end;
  1132.  
  1133. var
  1134.   Param: string;
  1135.   C: Char;
  1136.   T: PTopic;
  1137.   I: Integer;
  1138.  
  1139.   KeyFile: Text;
  1140.   KeyStr: string;
  1141.  
  1142.   BoldFile: Text;
  1143.   BoldStr: string;
  1144.  
  1145.   SwapFileSize: Longint;
  1146.  
  1147.   F: file;
  1148.  
  1149. begin
  1150.   WriteLn;
  1151.   WriteLn ('=== Int2RTF Interrupt List Compiler v0.9 Copyright (C) 1996 Slava Gostrenko ===');
  1152.   WriteLn;
  1153.  
  1154.   for I := 1 to ParamCount do begin
  1155.     Param := StUpcase2 (ParamStr (I));
  1156.     if Param [1] in ['/', '\', '-'] then
  1157.       if Param [2] in ['?', 'H'] then begin
  1158.         WriteLn ('Converts Ralf Brown''s Interrupt List into Rich Text Format (.RTF)');
  1159.         WriteLn ('to compile it further into windows help file (.HLP) with HC31.EXE.');
  1160.         WriteLn;
  1161.         WriteLn ('Usage: Int2RTF <enter>');
  1162.         Exit;
  1163.       end;
  1164.   end;
  1165.  
  1166.   SwapFileSize := Longint (5120)*1024 - MemAvail;
  1167.   if SwapFileSize > 0 then
  1168.     SwapFileSize := SwapFileSize and (-1024)
  1169.   else
  1170.     SwapFileSize := 0;
  1171.   if SwapFileSize > 0 then begin
  1172.     MemInitSwapFile ('int2rtf.swp', SwapFileSize);
  1173.     WriteLn ('swap file size - ', SwapFileSize);
  1174.   end;
  1175.  
  1176.   New (SwapFile, Init ('topics.swp', stCreate, 2048));
  1177.  
  1178.   Hdrs. Init (256, 256);
  1179.  
  1180.   FO. Init ('intwin.rtf', stCreate, 32768);
  1181.   Assign (IncompPattern, 'incomplt.log');
  1182.   Rewrite (IncompPattern);
  1183.  
  1184.   New (T, Init (16, 16));
  1185.   T^. AddString ('Visit the home page of Slava Gostrenko at http://sunny.aha.ru/~gw/');
  1186.   T^. AddString (' ');
  1187.   T^. AddString ('There you may check for the latest versions of Int2RTF and other software.');
  1188.   T^. AddString (' ');
  1189.   T^. AddString ('=== ARVID AUDIO ===');
  1190.   T^. AddString (' ');
  1191.   T^. AddString ('is a CD quality digital audio tape recorder made of Sound Blaster sound card');
  1192.   T^. AddString ('and  Arvid  streamer  board.  Arvid is a PC board priced at as little as $70');
  1193.   T^. AddString ('that  makes  a  streamer  of your home video tape recorder. It is capable of');
  1194.   T^. AddString ('storing  2  GigaBytes of data on a single tape. With the help of Arvid Audio');
  1195.   T^. AddString ('software you may record 3 hours of digital audio sound on a regular 180 min.');
  1196.   T^. AddString ('videotape.  Arvid  Audio  records from all audio sources available on(via) a');
  1197.   T^. AddString ('Sound Blaster sound card, e.i. CD player, Microphone, Line In. And now it is');
  1198.   T^. AddString ('capable  of  Direct  Digital Recording From CD! Download it now and you will');
  1199.   T^. AddString ('get 3 hours of 44.1 kHz 16 bit stereo sound on a $2 videotape! Visit my home');
  1200.   T^. AddString ('page for more info and references.');
  1201.   T^. AddString (' ');
  1202.   T^. AddString ('=== CD2WAV ===');
  1203.   T^. AddString (' ');
  1204.   T^. AddString ('is  a  CD-DA  (Digital  Audio)  grabber  with  an advanced jitter correction');
  1205.   T^. AddString ('algorithm.');
  1206.   T^. AddString (' ');
  1207.   T^. AddString ('=== INT2TPH ===');
  1208.   T^. AddString (' ');
  1209.   T^. AddString ('is  a  program  that converts Ralf Brown''s Interrupt List into Borland Turbo');
  1210.   T^. AddString ('Help File (.TPH file format) to use it with Turbo Help TSR or within Borland');
  1211.   T^. AddString ('(Turbo)  Pascal  IDE. Int2TPH uses hypertext features of the Interrupt List.');
  1212.   T^. AddString ('It  is  the  first  (and the only) Interrupt List compiler that makes a real');
  1213.   T^. AddString ('hypertext  of  the  Interrupt  List.  It is made possible due to an advanced');
  1214.   T^. AddString ('pattern  processing  technique  used  in  the  compiler. Not only it creates');
  1215.   T^. AddString ('comprehensive  indexes  for  all  the  topics in the list but it also allows');
  1216.   T^. AddString ('users to add their own indexes to the help file. Int2TPH is distributed with');
  1217.   T^. AddString ('source texts!');
  1218.   T^. AddString (' ');
  1219.   T^. AddString ('=== BORLAND PASCAL AUTO CORRECTOR ===');
  1220.   T^. AddString (' ');
  1221.   T^. AddString ('is  a  program  that  makes  it much easier to edit your programs in Borland');
  1222.   T^. AddString ('Pascal''s  IDE. Using expandable dictionary BP Auto Corrector beautifies your');
  1223.   T^. AddString ('sources  on  the fly. Type "tmysuperobject" and look at the screen. You will');
  1224.   T^. AddString ('see "TMySuperObject". And you do not have to press shift keys to type such a');
  1225.   T^. AddString ('nice  identifiers.  AutoSave  feature  will unglue your hands from <F2> key.');
  1226.   T^. AddString ('VideoSubst  feature  will enable Borland Pascal''s IDE to work in video modes');
  1227.   T^. AddString ('others  than 80x25 and 80x50. Now you may set up your BP to work in any text');
  1228.   T^. AddString ('video  mode  that  is  supported  by your video card. You may use VESA video');
  1229.   T^. AddString ('modes  too  and enjoy modes with the resolution up to 132x60! Auto Corrector');
  1230.   T^. AddString ('includes  patches  for BP to make a real full screen editor with no menu and');
  1231.   T^. AddString ('status  lines. It means 2 more lines will be used for displaying your source');
  1232.   T^. AddString ('texts.');
  1233.   T^. AddString (' ');
  1234.   T^. AddString ('=== TICKTOSS ===');
  1235.   T^. AddString (' ');
  1236.   T^. AddString ('is a fileechoprocessor for end-user fidonet systems. TickToss is just a .bat');
  1237.   T^. AddString ('file.  No  .exe''s  or  .com''s.  But it has all the features an end-user ever');
  1238.   T^. AddString ('needs. Automatic creation of new fileechoes with meaningful directory names.');
  1239.   T^. AddString ('Creating  and  updating of area configuration file. Creating and updating of');
  1240.   T^. AddString ('files.bbs''s  in  your  fileecho  areas.  Support  for  long  multilined file');
  1241.   T^. AddString ('descriptions. Logging of performed actions. And all the abovelisted features');
  1242.   T^. AddString ('are implemented as a single .bat file. TickToss requires 4dos or compaitable');
  1243.   T^. AddString ('command processor.');
  1244.   T^. AddString (' ');
  1245.   T^. AddString ('=== And MORE... ===');
  1246.   T^. AddString (' ');
  1247.   T^. AddString ('Visit my homepage NOW! ;-)');
  1248.   T^. AddString (' ');
  1249.   FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1250.       'http://sunny.aha.ru/~gw/', 0, T)));
  1251.  
  1252.   for I := Low (IntLists) to High (IntLists) do begin
  1253.     New (IntLists [I], Init (16, 16));
  1254.     IntNames [I] := MakeCorrectTopicName ('INT ' + HexByte (I));
  1255.   end;
  1256.  
  1257.   New (IntListIndex, Init (16, 16));
  1258.   IntListIndexName := MakeCorrectTopicName (' INTERRUPT LIST INDEX ');
  1259.  
  1260.   Assign (Interrup1st, 'interrup.1st');
  1261.   {$I-}
  1262.   Reset (Interrup1st);
  1263.   {$I+}
  1264.   if IOResult = 0 then begin
  1265.     if not EOF (Interrup1st) then begin
  1266.       ReadLn (Interrup1st, CopyrightStr);
  1267.       Tab2Spc (CopyrightStr);
  1268.       while Pos ('       ', CopyrightStr) > 0 do
  1269.         Delete (CopyrightStr, Pos ('       ', CopyrightStr), 1);
  1270.       if CopyrightStr <> '' then
  1271.         IntListIndex^. SetHeader (CopyrightStr);
  1272.  
  1273.       if not EOF (Interrup1st) then begin
  1274.         ReadLn (Interrup1st, CopyrightStr);
  1275.         Tab2Spc (CopyrightStr);
  1276.         if CopyrightStr <> '' then
  1277.           IntListIndex^. SetSubHeader (CopyrightStr);
  1278.       end;
  1279.     end;
  1280.  
  1281.     Close (Interrup1st);
  1282.   end;
  1283.  
  1284.   IntListIndex^.AddString (' ===    This help file was compiled with    ===');
  1285.   IntListIndex^.AddString (' === Int2RTF v0.9 (C) 1996 Slava Gostrenko. ===');
  1286.   IntListIndex^.AddKeyword ('http://sunny.aha.ru/~gw/', 0);
  1287.   IntListIndex^.AddString (' === '#2'http://sunny.aha.ru/~gw/'#2' or gw@aha.ru, ===');
  1288.   IntListIndex^.AddString (' === FidoNet 2:5020/201.105,2:5020/468.105. ===');
  1289.   IntListIndex^.AddString (' ');
  1290.   IntListIndex^.AddKeyword ('TITLES', 0);
  1291.   IntListIndex^.AddString (' '#2'Interrupts'#2);
  1292.  
  1293.   KeyLists. Init (1, 1);
  1294.   KeyNames. Init (1, 1);
  1295.   Assign (KeyFile, 'int_keys.txt');
  1296.   {$I-}
  1297.   Reset (KeyFile);
  1298.   {$I+}
  1299.   if IOResult = 0 then begin
  1300.     while not EOF (KeyFile) do begin
  1301.       ReadLn (KeyFile, KeyStr);
  1302.       if KeyStr <> '' then begin
  1303.         KeyLists. AtInsert (KeyLists. Count, New (PTopic, Init (1, 1)));
  1304.         KeyStr := MakeCorrectTopicName (KeyStr);
  1305.         KeyNames. AtInsert (KeyNames. Count, NewStr (KeyStr));
  1306.  
  1307.         IntListIndex^.AddKeyword (KeyStr, 0);
  1308.         IntListIndex^.AddString (' '#2 + KeyStr + #2);
  1309.       end;
  1310.     end;
  1311.  
  1312.     Close (KeyFile);
  1313.   end;
  1314.  
  1315.   BoldNames. Init (1, 1);
  1316.   Assign (BoldFile, 'int_bold.txt');
  1317.   {$I-}
  1318.   Reset (BoldFile);
  1319.   {$I+}
  1320.   if IOResult = 0 then begin
  1321.     while not EOF (BoldFile) do begin
  1322.       ReadLn (BoldFile, BoldStr);
  1323.       if BoldStr <> '' then
  1324.         BoldNames. AtInsert (BoldNames. Count, NewStr (BoldStr));
  1325.     end;
  1326.  
  1327.     Close (BoldFile);
  1328.   end;
  1329.  
  1330.   New (IntList, Init (16, 16));
  1331.   IntListName := MakeCorrectTopicName ('Interrupt List Misc. Stuff');
  1332.   IntListIndex^.AddKeyword (IntListName, 0);
  1333.   IntListIndex^.AddString (' '#2 + IntListName + #2);
  1334.  
  1335.   New (Tables, Init (16, 16));
  1336.   TablesName := MakeCorrectTopicName ('Tables');
  1337.   IntListIndex^.AddKeyword (TablesName, 0);
  1338.   IntListIndex^.AddString (' '#2 + TablesName + #2);
  1339.  
  1340.   New (CMOS, Init (16, 16));
  1341.   CMOSName := MakeCorrectTopicName ('CMOS');
  1342.   IntListIndex^.AddKeyword (CMOSName, 0);
  1343.   IntListIndex^.AddString (' '#2 + CMOSName + #2);
  1344.  
  1345.   New (FarCall, Init (16, 16));
  1346.   FarCallName := MakeCorrectTopicName ('Far Calls');
  1347.   IntListIndex^.AddKeyword (FarCallName, 0);
  1348.   IntListIndex^.AddString (' '#2 + FarCallName + #2);
  1349.  
  1350.   New (Memory, Init (16, 16));
  1351.   MemoryName := MakeCorrectTopicName ('Memory');
  1352.   IntListIndex^.AddKeyword (MemoryName, 0);
  1353.   IntListIndex^.AddString (' '#2 + MemoryName + #2);
  1354.  
  1355.   New (Ports, Init (16, 16));
  1356.   PortSName := MakeCorrectTopicName ('Ports');
  1357.   IntListIndex^.AddKeyword (PortsName, 0);
  1358.   IntListIndex^.AddString (' '#2 + PortsName + #2);
  1359.  
  1360.   ProcessInterrup ('interrup.1st', '');
  1361.   ProcessInterrup ('category.key', '');
  1362.   ProcessInterrup ('86bugs.lst', '86 Bugs');
  1363.   IntListIndex^.AddKeyword ('86 Bugs', 0);
  1364.   IntListIndex^.AddString (' '#2'86 Bugs'#2);
  1365.   ProcessInterrup ('biblio.lst', '');
  1366.   ProcessInterrup ('cmos.lst', '');
  1367.   ProcessInterrup ('farcall.lst', '');
  1368.   ProcessInterrup ('glossary.lst', 'Glossary of The Interrupt List');
  1369.   IntListIndex^.AddKeyword ('Glossary of The Interrupt List', 0);
  1370.   IntListIndex^.AddString (' '#2'Glossary of The Interrupt List'#2);
  1371.   ProcessInterrup ('memory.lst', '');
  1372.   ProcessInterrup ('opcodes.lst', 'Opcodes List');
  1373.   IntListIndex^.AddKeyword ('Opcodes List', 0);
  1374.   IntListIndex^.AddString (' '#2'Opcodes List'#2);
  1375.   ProcessInterrup ('overview.lst', '');
  1376.   ProcessInterrup ('ports.lst', '');
  1377.   ProcessInterrup ('tables.lst', '');
  1378.   ProcessInterrup ('interrup.pri', 'Interrupt Primer');
  1379.   IntListIndex^.AddKeyword ('Interrupt Primer', 0);
  1380.   IntListIndex^.AddString (' '#2'Interrupt Primer'#2);
  1381.   ProcessInterrup ('rbrown.txt', 'Ralf Brown');
  1382.   IntListIndex^.AddKeyword ('Ralf Brown', 0);
  1383.   IntListIndex^.AddString (' '#2'Ralf Brown'#2);
  1384.  
  1385.   if not ProcessInterrup ('interrup.lst', '') then
  1386.     for C := 'a' to 'z' do
  1387.       if not ProcessInterrup ('interrup.' + C, '') then
  1388.         Break;
  1389.  
  1390.   FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1391.     PortsName, 0, Ports)));
  1392.  
  1393.   FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1394.     MemoryName, 0, Memory)));
  1395.  
  1396.   FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1397.     FarCallName, 0, FarCall)));
  1398.  
  1399.   FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1400.     CMOSName, 0, CMOS)));
  1401.  
  1402.   FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1403.     TablesName, 0, Tables)));
  1404.  
  1405.   FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1406.     IntListName, 0, IntList)));
  1407.  
  1408.   if KeyLists. Count > 0 then
  1409.     for I := 0 to KeyLists. Count - 1 do
  1410.       FO. IDXTbl. Insert (New (PIndexEntry, Init (
  1411.         PString (KeyNames. At (I))^, 0, PTopic (KeyLists. Items^ [I]))));
  1412.  
  1413.   FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1414.     IntListIndexName, 0, IntListIndex)));
  1415.  
  1416.   for I := Low (IntLists) to High (IntLists) do
  1417.     FO. IdxTbl. Insert (New (PIndexEntry, Init (
  1418.       IntNames [I], 0, IntLists [I])));
  1419.  
  1420.   Close (IncompPattern);
  1421.   FO. Done;
  1422.  
  1423.   WriteLn (Hdrs. Count, ' topics processed.');
  1424.   Hdrs. Done;
  1425.  
  1426.   SwapFile^.Seek (0);
  1427.   SwapFile^.Truncate;
  1428.   Dispose (SwapFile, Done);
  1429.   Assign (F, 'topics.swp');
  1430.   Erase (F);
  1431.  
  1432.   if SwapFileSize > 0 then
  1433.     MemCloseSwapFile (1);
  1434. end.
  1435.